package top.anka1.fxgui;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;

import top.anka1.ims.*;
import top.anka1.ims.RestaurantManagementSystem.Meal;
import top.anka1.ims.RestaurantManagementSystem.RestaurantBilling;

import java.util.ArrayList;
/**
 * Controller class for displaying and managing restaurant orders.
 * It allows users to view, remove meals from, and cancel orders.
 * @author Anka
 */
public class GenerateBillController {
    private RestaurantGUI restaurantGUI;
    private Stage stage;
    private int id;
    private String customerName;
    private BankingService bankingService;
    @FXML
    private TextField orderIDField;
    @FXML
    private TextField customerNameField;
    @FXML
    private TableView<Meal> orderTable;
    @FXML
    private TableColumn<Meal, String> mealNameColumn;
    @FXML
    private TableColumn<Meal, Double> mealPriceColumn;
    @FXML
    private Label payReminderLabel;
    @FXML
    private TextField bankAccountField;
    @FXML
    private Button payButton;

    public void setData(RestaurantGUI restaurantGUI, BankingService bankingService, Stage stage) {
        this.restaurantGUI = restaurantGUI;
        this.bankingService = bankingService;
        this.stage = stage;
        mealNameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
        mealNameColumn.setStyle("-fx-alignment: CENTER;");
        mealPriceColumn.setCellValueFactory(new PropertyValueFactory<>("totalPrice"));
        mealPriceColumn.setStyle("-fx-alignment: CENTER;");
        mealPriceColumn.setCellFactory(column -> new javafx.scene.control.cell.TextFieldTableCell<>(
                new javafx.util.converter.DoubleStringConverter() {
                    @Override
                    public String toString(Double value) {
                        if (value == null) return "";
                        return String.format("¥%.2f", value);
                    }
                }
        ));
        orderTable.setPlaceholder(new Label("No meals in the order"));
    }

    public void showError(String title, String headerText, String contentText) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.initOwner(stage);
        alert.setTitle(title);
        alert.setHeaderText(headerText);
        alert.setContentText(contentText);
        alert.showAndWait();
    }

    public void showInformation(String title, String headerText, String contentText) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.initOwner(stage);
        alert.setTitle(title);
        alert.setHeaderText(headerText);
        alert.setContentText(contentText);
        alert.showAndWait();
    }

    @FXML
    public void checkOrder() {
        String orderID = orderIDField.getText();
        customerName = customerNameField.getText();
        if (orderID.isEmpty()) {
            showError("Error", "Order ID is empty", "Please enter a valid Order ID.");
            return;
        } else if (customerName.isEmpty()) {
            showError("Error", "Customer name is empty", "Please enter a valid customer name.");
            return;
        }
        try {
            id = Integer.parseInt(orderID);
            RestaurantBilling order = restaurantGUI.getRestaurantService().getOrderById(id);
            if (order == null) {
                showError("Error", "Order not found", "No order found with the given ID.");
                return;
            }
            ArrayList<Meal> orderList = order.getOrderList();
            ObservableList<Meal> meals = FXCollections.observableArrayList(orderList);
            orderTable.setItems(meals);
            double totalPrice = order.calculateBill();
            payReminderLabel.setText("Dear " + customerName +", the amount of your current consumption is" + String.format("Total Price: ¥%.2f", totalPrice) + "\nPlease enter your bank account in order to pay for the bill.");
            bankAccountField.setVisible(true);
            bankAccountField.setPromptText("Bank Account");
            payButton.setVisible(true);
        } catch (NumberFormatException e) {
            showError("Error", "Invalid Order ID. Please enter a valid numeric Order ID.", "Error: " + e.getMessage());
        }
    }
    @FXML
    public void payByBankAccount() {
        String bankAccount = bankAccountField.getText();
        if (bankAccount.isEmpty()) {
            showError("Error", "Bank account is empty", "Please enter a valid bank account.");
            return;
        }
        try {
            double totalPrice = restaurantGUI.getRestaurantService().getOrderById(id).calculateBill();
            if (bankingService.withdrawWithSpecifiedTask(bankAccount, totalPrice, "Payment for the meal (Order ID: " + id + ")")) {
                showInformation("Payment Successful", "Thank you for your payment, " + customerName + "!", "Now your account balance is: " + bankingService.getBalance(bankAccount));
                stage.close();
            } else {
                showError("Payment Failed", "Payment Failed", "Insufficient funds or invalid account.");
            }
        } catch (Exception e) {
            showError("Error", "Payment Error", "An error occurred while processing the payment: " + e.getMessage());
        }
    }
}
